import { _decorator, Component, director, game, Node, Rect, UITransform, Vec2, Vec3 } from 'cc';
import { Bound } from './QuadTree';
const { ccclass, property } = _decorator;

class Vector2 {
    constructor(public x: number, public y: number) { }
    toString(): string {
        return `(${this.x},${this.y})`
    }
    equals(other: Vector2): boolean {
        return this.x === other.x && this.y === other.y;
    }
}

class MyRect {
    constructor(public position: Vector2, public size: Vector2) {
    }

    GetBound(): Bound {
        return {
            x: this.position.x - this.size.x / 2,
            y: this.position.y - this.size.y / 2,
            width: this.size.x,
            height: this.size.y
        }
    }

}

type Obj = Node;
export class SpatialHash {

    cellSize: number;
    cellMap = new Map<string, Obj[]>();

    constructor(size: number) {
        this.init(size);
    }

    init(size: number) {
        this.cellSize = size;
        this.cellMap = new Map<string, Obj[]>();
    }

    getCellPosition(position: Vector2): Vector2 {
        return new Vector2(div(position.x, this.cellSize), div(position.y, this.cellSize));
    }

    insert(obj: Obj) {
        const box = obj.getComponent(UITransform).getBoundingBox();
        this.insertBox(obj, new Vector2(box.xMin, box.yMin));
        this.insertBox(obj, new Vector2(box.xMin, box.yMax));
        this.insertBox(obj, new Vector2(box.xMax, box.yMin));
        this.insertBox(obj, new Vector2(box.xMax, box.yMax));
    }

    private insertBox(obj: Obj, v: Vector2) {
        let pos = this.getCellPosition(v) + '';
        if (!this.cellMap.has(pos)) {
            this.cellMap.set(pos, []);
        }
        this.cellMap.get(pos).push(obj);
    }

    query(obj: Obj): Obj[] {
        const box = obj.getComponent(UITransform).getBoundingBox();
        let list: Obj[] = []
        list = list.concat(this.getList(new Vector2(box.xMin, box.yMin)));
        list = list.concat(this.getList(new Vector2(box.xMin, box.yMax)));
        list = list.concat(this.getList(new Vector2(box.xMax, box.yMin)));
        list = list.concat(this.getList(new Vector2(box.xMax, box.yMax)));

        list = list.filter(function (item, index) {
            return list.indexOf(item) >= index;
        });
        return list;
    }

    private getList(vector2: Vector2): Obj[] {
        let pos = this.getCellPosition(vector2) + '';
        if (this.cellMap.has(pos)) {
            return this.cellMap.get(pos);
        }
        return [];
    }

    clear() {
        this.cellMap.clear();
    }

    onClickOpen() {
        game.restart();
        // director.loadScene(director);
    }
}

function div(num: number, d: number) {
    if (d == 0) { return 0 }
    if (num == 0) { return -1; }
    return Math.floor(num / d);
}